package com.harmony.pilot.knowledge.entity;

import lombok.Data;
import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 代码文件实体
 * 记录每个源代码文件的完整信息
 */
@Data
@Entity
@Table(name = "code_file", indexes = {
    @Index(name = "idx_file_path", columnList = "file_path"),
    @Index(name = "idx_file_type", columnList = "file_type"),
    @Index(name = "idx_module", columnList = "module_name")
})
public class CodeFile {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    /** 文件完整路径 */
    @Column(name = "file_path", nullable = false, length = 1000, unique = true)
    private String filePath;
    
    /** 文件名 */
    @Column(name = "file_name", nullable = false, length = 255)
    private String fileName;
    
    /** 文件类型 (.h, .cpp, .c, .gn等) */
    @Column(name = "file_type", nullable = false, length = 20)
    private String fileType;
    
    /** 相对路径 (相对于ohcode根目录) */
    @Column(name = "relative_path", length = 1000)
    private String relativePath;
    
    /** 所属模块 (如arkcompiler, foundation等) */
    @Column(name = "module_name", length = 255)
    private String moduleName;
    
    /** 所属子模块 */
    @Column(name = "sub_module", length = 255)
    private String subModule;
    
    /** 目录深度 */
    @Column(name = "depth_level")
    private Integer depthLevel;
    
    /** 文件大小(字节) */
    @Column(name = "file_size")
    private Long fileSize;
    
    /** 代码行数 */
    @Column(name = "line_count")
    private Integer lineCount;
    
    /** 文件内容MD5 (用于检测变更) */
    @Column(name = "content_md5", length = 32)
    private String contentMd5;
    
    /** 版权信息 */
    @Column(name = "copyright", columnDefinition = "TEXT")
    private String copyright;
    
    /** 许可证信息 */
    @Column(name = "license", length = 500)
    private String license;
    
    /** 作者信息 */
    @Column(name = "authors", columnDefinition = "TEXT")
    private String authors;
    
    /** 文件描述/注释 */
    @Column(name = "description", columnDefinition = "TEXT")
    private String description;
    
    /** 是否是测试文件 */
    @Column(name = "is_test")
    private Boolean isTest = false;
    
    /** 是否是Mock文件 */
    @Column(name = "is_mock")
    private Boolean isMock = false;
    
    /** 是否是Fuzzer文件 */
    @Column(name = "is_fuzzer")
    private Boolean isFuzzer = false;
    
    /** 是否是头文件 */
    @Column(name = "is_header")
    private Boolean isHeader = false;
    
    /** 文件最后修改时间 */
    @Column(name = "last_modified")
    private LocalDateTime lastModified;
    
    /** 扫描时间 */
    @Column(name = "scanned_at")
    private LocalDateTime scannedAt;
    
    /** 解析状态 (PENDING, PARSING, SUCCESS, FAILED) */
    @Column(name = "parse_status", length = 20)
    private String parseStatus = "PENDING";
    
    /** 解析错误信息 */
    @Column(name = "parse_error", columnDefinition = "TEXT")
    private String parseError;
    
    /** 关联的类定义 */
    @OneToMany(mappedBy = "codeFile", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<ClassDefinition> classes = new ArrayList<>();
    
    /** 关联的函数定义 */
    @OneToMany(mappedBy = "codeFile", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<FunctionDefinition> functions = new ArrayList<>();
    
    /** 关联的Include依赖 */
    @OneToMany(mappedBy = "sourceFile", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<IncludeDependency> includeDependencies = new ArrayList<>();
    
    /** 关联的宏定义 */
    @OneToMany(mappedBy = "codeFile", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<MacroDefinition> macros = new ArrayList<>();
    
    /** 创建时间 */
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;
    
    /** 更新时间 */
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
        updatedAt = LocalDateTime.now();
        scannedAt = LocalDateTime.now();
    }
    
    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
    }
}

